package com.example.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.mapper.DepartmentMapper;
import com.example.pojo.Department;
import com.example.pojo.PageBean;
import com.example.service.DepartmentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author testjava
 * @since 2022-08-20
 */
@Service
public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, Department> implements DepartmentService {
    @Autowired
    private DepartmentMapper departmentMapper;

    @Override
    public List<Department> selectWithParent(Integer parentId) {
        return departmentMapper.selectWithParent(parentId);
    }

    @Override
    public List<Department> selectList(Integer parentId) {
        List<Department> list = null;

        //子集展示
        if (parentId != null) {
            LambdaQueryWrapper<Department> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Department::getParentId, parentId);
            list = this.list(wrapper);
        } else {
            list = this.selectWithParent(parentId);
        }
        return list;
    }

    @Override
    public List<Department> getDeptTree(Integer parentId) {
        //先查出根部门
        LambdaQueryWrapper<Department> wrapper = new LambdaQueryWrapper<>();
        wrapper.isNull(parentId == null, Department::getParentId);
        wrapper.eq(parentId != null, Department::getParentId, parentId);
        List<Department> rootList = list(wrapper);

        ArrayList<Department> allList = new ArrayList<>();
        //根据根部门查出子部门
        getChildrenTree(rootList, allList, 0);

        return allList;
    }

    /**
     * 根据根部门查出子部门，放入部门集合中
     *
     * @param rootList 根部门
     * @param list     全部部门
     * @param height   树的高度
     */
    public void getChildrenTree(List<Department> rootList, List<Department> list, Integer height) {
        for (Department department : rootList) {
            //给部门名称字段添加前缀
            StringBuilder prefix = new StringBuilder();
            for (int i = 0; i < height; i++) {
                prefix.append("&nbsp;&nbsp;&nbsp;&nbsp;");
            }

            prefix.append("┣");
            department.setName(prefix + department.getName());

            //放入总集合
            list.add(department);
            Integer parentId = department.getDepid();
            //根据父ID查子集
            LambdaQueryWrapper<Department> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(parentId != null, Department::getParentId, parentId);
            List<Department> listChildren = list(wrapper);

            getChildrenTree(listChildren, list, ++height);

            //高度回退
            --height;
        }
    }

    @Override
    public List<Department> getParentTree(Integer id) {
        //从总例表里删除
        List<Department> deptTree = getDeptTree(null);
        //从列表中删除当前部门
        for (int i = 0; i < deptTree.size(); i++) {
            if (deptTree.get(i).getDepid() == id) {
                deptTree.remove(i);
                i--;
            }
        }
        //从列表中删除子部门
        delSon(getById(id).getDepid(), deptTree);

        return deptTree;
    }

    private void delSon(Integer parentId, List<Department> deptTree) {
        for (int i = 0; i < deptTree.size(); i++) {
            if (parentId.equals(deptTree.get(i).getParentId())) {
                Integer thisId = deptTree.get(i).getDepid();
                //删除他的子部门
                delSon(thisId, deptTree);
                //删除当前部门
                deptTree.remove(i);
                i--;
            }
        }
    }

    @Override
    public boolean deleteDeptAndSon(Integer id) {
        delAndSon(id);
        return true;
    }

    @Override
    public PageBean<Department> getPage(Integer parentId,Integer currentPage, Integer pageSize) {
        Integer page = (currentPage - 1) * pageSize;
        List<Department> departmentList = departmentMapper.getPage(parentId,page,pageSize);
        //求出数量
        LambdaQueryWrapper<Department> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(parentId != null, Department::getParentId, parentId);
        wrapper.isNull(parentId == null, Department::getParentId);
        int count = count(wrapper);

        return new PageBean<>(currentPage, pageSize, count, departmentList);
    }

    @Transactional(rollbackFor = {Exception.class})
    void delAndSon(Integer id) {
        //查询其子部门
        LambdaQueryWrapper<Department> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(id != null, Department::getParentId, id);
        List<Department> children = list(wrapper);
        for (Department child : children) {
            //递归删除
            delAndSon(child.getDepid());
            removeById(child);
        }
        removeById(id);
    }
}
